package controllers

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
	"github.com/xuri/excelize/v2"
)

// DownloadDataAsExcel 将接口数据转换为 Excel 格式并返回
func (server *Server) GetFb(ctx *gin.Context) {
	const (
		baseURL = "https://open-api-fractal.unisat.io/v1/address/fb/balances?start=0&limit=20"
		limit   = 500 // 每页数据量
		delay   = 1   // 请求间隔时间，单位秒
	)

	start := 0
	var apiResponse APIResponse
	excelData := map[string]HolderDetail{}

	// 分页加载数据
	for {
		url := fmt.Sprintf("%s?start=%d&limit=%d", baseURL, start, limit)
		log.Printf("Fetching data from URL: %s\n", url)

		body, err := fetchPageData(url)
		if err != nil {
			log.Printf("Error fetching data from URL %s: %v", url, err)
			ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			return
		}

		if err := json.Unmarshal(body, &apiResponse); err != nil {
			log.Printf("Error unmarshalling API response: %v", err)
			continue
		}

		// 检查是否还有数据
		if len(apiResponse.Data.Detail) == 0 {
			log.Println("No more data available")
			break
		}

		// 获取每个地址的余额数据
		for _, v := range apiResponse.Data.Detail {
			fmt.Println(v)
			excelData[v.Address] = HolderDetail{
				Address:                v.Address,
				OverallBalance:         v.OverallBalance,
				TransferableBalance:    v.TransferableBalance,
				AvailableBalance:       v.AvailableBalance,
				AvailableBalanceSafe:   v.AvailableBalanceSafe,
				AvailableBalanceUnSafe: v.AvailableBalanceUnSafe,
			}
		}
		start += limit
	}
	// 生成 Excel 文件
	file := excelize.NewFile()
	sheetName := "Holders"
	index, _ := file.NewSheet(sheetName)

	// 设置表头
	file.SetCellValue(sheetName, "A1", "Address")
	file.SetCellValue(sheetName, "G1", "Satoshi")
	file.SetCellValue(sheetName, "B1", "OverallBalance")
	file.SetCellValue(sheetName, "C1", "TransferableBalance")
	file.SetCellValue(sheetName, "D1", "AvailableBalance")
	file.SetCellValue(sheetName, "E1", "AvailableBalanceSafe")
	file.SetCellValue(sheetName, "F1", "AvailableBalanceUnSafe")

	overallBalanceTotal := 0.0
	transferableBalanceTotal := 0.0
	availableBalanceTotal := 0.0
	availableBalanceSafeTotal := 0.0
	availableBalanceUnSafeTotal := 0.0

	row := 0
	// 填充数据
	for _, data := range excelData {
		row += 1
		// 强制转换为 float64
		overallBalance, _ := strconv.ParseFloat(fmt.Sprintf("%v", data.OverallBalance), 64)
		transferableBalance, _ := strconv.ParseFloat(fmt.Sprintf("%v", data.TransferableBalance), 64)
		availableBalance, _ := strconv.ParseFloat(fmt.Sprintf("%v", data.AvailableBalance), 64)
		availableBalanceSafe, _ := strconv.ParseFloat(fmt.Sprintf("%v", data.AvailableBalanceSafe), 64)
		availableBalanceUnSafe, _ := strconv.ParseFloat(fmt.Sprintf("%v", data.AvailableBalanceUnSafe), 64)

		overallBalance = overallBalance / 100000000
		transferableBalance = transferableBalance / 100000000
		availableBalance = availableBalance / 100000000
		availableBalanceSafe = availableBalanceSafe / 100000000
		availableBalanceUnSafe = availableBalanceUnSafe / 100000000

		overallBalanceTotal += overallBalance
		transferableBalanceTotal += transferableBalance
		availableBalanceTotal += availableBalance
		availableBalanceSafeTotal += availableBalanceSafe
		availableBalanceUnSafeTotal += availableBalanceUnSafe
		// 写入 Excel
		file.SetCellValue(sheetName, fmt.Sprintf("A%d", row), data.Address)
		file.SetCellValue(sheetName, fmt.Sprintf("B%d", row), overallBalance)
		file.SetCellValue(sheetName, fmt.Sprintf("C%d", row), transferableBalance)
		file.SetCellValue(sheetName, fmt.Sprintf("D%d", row), availableBalance)
		file.SetCellValue(sheetName, fmt.Sprintf("E%d", row), availableBalanceSafe)
		file.SetCellValue(sheetName, fmt.Sprintf("F%d", row), availableBalanceUnSafe)
	}
	file.SetCellValue(sheetName, fmt.Sprintf("A%d", row+1), "总计")
	file.SetCellValue(sheetName, fmt.Sprintf("B%d", row+1), overallBalanceTotal)
	file.SetCellValue(sheetName, fmt.Sprintf("C%d", row+1), transferableBalanceTotal)
	file.SetCellValue(sheetName, fmt.Sprintf("D%d", row+1), availableBalanceTotal)
	file.SetCellValue(sheetName, fmt.Sprintf("E%d", row+1), availableBalanceSafeTotal)
	file.SetCellValue(sheetName, fmt.Sprintf("F%d", row+1), availableBalanceUnSafeTotal)

	// 设置工作表为当前活动工作表
	file.SetActiveSheet(index)

	// 返回 Excel 文件
	fileName := "holders_data.csv"
	ctx.Header("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
	ctx.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", fileName))
	if err := file.Write(ctx.Writer); err != nil {
		log.Printf("Failed to write excel file: %v", err)
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to generate Excel file"})
		return
	}
}
